package com.feicheng.service.impl;

// MLGBD
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.feicheng.common.constant.Constant;
import com.feicheng.common.exception.SystemException;
import com.feicheng.common.message.LoginMessage;
import com.feicheng.common.result.ResultInfo;
import com.feicheng.persistence.entity.Permission;
import com.feicheng.persistence.entity.Role;
import com.feicheng.persistence.entity.RolePermission;
import com.feicheng.persistence.entity.User;
import com.feicheng.persistence.entity.UserRole;
import com.feicheng.persistence.service.IPermissionService;
import com.feicheng.persistence.service.IRolePermissionService;
import com.feicheng.persistence.service.IRoleService;
import com.feicheng.persistence.service.IUserRoleService;
import com.feicheng.persistence.service.IUserService;
import com.feicheng.service.BaseService;
import com.feicheng.service.IFLoginService;

/**
 * 管理平台端使用用户名和密码验证登录
 * @see com.feicheng.service.IFLoginService
 */
@Service
public class FAdminPasswordLoginServiceImpl extends BaseService implements IFLoginService {

    @Autowired
    IUserService iUserService;

    @Autowired
    IRoleService iRoleService;

    @Autowired
    IPermissionService iPermissionService;

    @Autowired
    IUserRoleService iUserRoleService;

    @Autowired
    IRolePermissionService iRolePermissionService;

    @Autowired
    LoginMessage loginMessage;

    /**
     * 登录逻辑
     * @see com.feicheng.service.IFLoginService#login(String)
     * @param loginParams 登录参数 包含 用户名 密码
     * @return
     */
    @Override
    public ResultInfo login(String loginParams) {

        /* 取得登录所需的参数 账户 和  密码 ，转换出现问题时抛出异常，登录逻辑停止。*/
        JSONObject param = null;
        try {
            param = JSONObject.parseObject(loginParams);
        } catch (JSONException exception) {
            throw new SystemException(loginMessage.getE01());
        }

        // 取得登录所需的参数 账户
        String account = param.getString(Constant.ENTITY.USER.ACCOUNT);

        /* 账户取得失败时抛出异常，登录逻辑停止。 */
        if (!StringUtils.hasLength(account)) {
            throw new SystemException(loginMessage.getE02());
        }

        /* 密码取得失败时抛出异常，登录逻辑停止。 */
        String password = param.getString(Constant.ENTITY.USER.PASSWORD);
        if (!StringUtils.hasLength(password)) {
            throw new SystemException(loginMessage.getE03());
        }

        /* 构建查询条件，以账户为条件。 */
        QueryWrapper<User> qw = new QueryWrapper<User>();
        qw.eq(Constant.ENTITY.USER.ACCOUNT, account);

        /* 查询用户 */
        List<User> resultList = iUserService.list(qw);

        /* 找不到记录时，账户不存在。逻辑停止 */
        if (null == resultList || resultList.size() == 0) {
            throw new SystemException(loginMessage.getE04());
        /* 找到多条记录时，账户非法。逻辑停止 */
        } else if (resultList.size() > 1) {
            throw new SystemException(loginMessage.getE05());
        }

        /* 找且只找到一条时，登录逻辑继续。 */
        User currentUser = resultList.get(0);

        /* 密码校验不相等时，密码错误，登录逻辑停止。 */
        // TODO 密码加密
        if (!currentUser.getPassword().equals(password)) {
            throw new SystemException(loginMessage.getE06());
        }

        /* 构建返回结果，要包含用户信息，角色信息，权限信息。 */
        JSONObject currentUserInfo = new JSONObject();

        //返回的密码要设置为空，不可见
        currentUser.setPassword(null);

        // 将用户信息保存到返回结果中
        currentUserInfo.put(Constant.RESULT.USER.USER, currentUser);

        /* 构建角色ID查询，以用户ID为查询条件，查询角色ID集合 */
        QueryWrapper<UserRole> qwUr = new QueryWrapper<UserRole>();
        qwUr.eq(Constant.ENTITY.USER.USER_ID, currentUser.getUserId());

        // 查询角色ID集合
        List<UserRole> userRoleList = iUserRoleService.list(qwUr);

        // 取得的角色ID保存到角色ID集合中
        Set<Integer> roleIds = new HashSet<Integer>();
        for (UserRole ur : userRoleList) {
            roleIds.add(ur.getRoleId());
        }

        // 构建角色查询，以角色ID集合为查询条件。
        QueryWrapper<Role> qwR = new QueryWrapper<Role>();
        qwR.in(Constant.ENTITY.ROLE.ROLE_ID, roleIds);

        // 查询角色
        List<Role> roleList = iRoleService.list(qwR);

        // 构建权限ID查询，以角色ID集合为查询条件
        QueryWrapper<RolePermission> qwRp = new QueryWrapper<RolePermission>();
        qwRp.in(Constant.ENTITY.ROLE.ROLE_ID, roleIds);

        // 查询权限ID集合
        List<RolePermission> rolePermissionList = iRolePermissionService.list(qwRp);

        /* 将取得的权限ID保存到权限ID集合中 */
        Set<Integer> permissionIds = new HashSet<Integer>();
        for (RolePermission rp : rolePermissionList) {
            permissionIds.add(rp.getPermissionId());
        }

        /* 构建权限查询，以权限ID集合为查询条件 */
        QueryWrapper<Permission> qwP = new QueryWrapper<Permission>();
        if (!permissionIds.isEmpty()) {
            qwP.in(Constant.ENTITY.PERMISSION.PERMISSION_ID, permissionIds);
        }
        qwP.eq(Constant.ENTITY.PERMISSION.STATU, Boolean.TRUE);
        qwP.orderByAsc(Constant.ENTITY.PERMISSION.PERMISSION_ID);

        // 查询权限
        List<Permission> permissionList = iPermissionService.list(qwP);

        /* 构建权限树 */
        List<Permission> pList = new ArrayList<Permission>();
        Map<Integer, Permission> permissionMap = new HashMap<Integer, Permission>();
        for (Permission p : permissionList) {

            if (0 == p.getPId()) {
                permissionMap.put(p.getPermissionId(), p);
                pList.add(p);
            } else {
                List<Permission> subPList =
                        permissionMap.get(p.getPId()).getPermissions();
                if (null == subPList) {
                    subPList = new ArrayList<Permission>();
                    permissionMap.get(p.getPId()).setPermissions(subPList);
                }
                subPList.add(p);
            }
        }

        // 将角色信息保存到返回结果中
        currentUserInfo.put(Constant.RESULT.ROLE.ROLES, roleList);

        // 将权限信息保存到返回结果中
        currentUserInfo.put(Constant.RESULT.PERMISSION.PERMISSIONS, pList);

        // 返回结果保存到session中
        super.setToken(Constant.RESULT.CURRENT, currentUserInfo);

        // 返回结果
        return ResultInfo.success(currentUserInfo);
    }
}
